<template>
  <div>
    <!-- 弹框 -->
    <!-- 当点击叉号的时候并没有修改父组件中的dialogVisible -->
    <!-- 在组件内部触发了一个自定义事件 close -->

    <!-- .sync: 加上这个修饰符之后 我们不再需要手动绑定一个close自定义事件点击叉号同样可以关闭弹框 -->
    <!-- 内部表现: 加上.sync修饰符之后形成了一个叫做 基于props的双向绑定 其实就是在内部自动绑定了一个函数 -->
    <!-- 在函数体力帮助我们完成了对于dialogVisible属性的自动赋值 -->
    <el-dialog
      title="提示"
      :visible="showDialog"
      width="30%"
      @close="closeDialog"
      @open="openDialog"
    >
      <!-- 表单 -->
      <!-- rules: 校验规则 -->
      <el-form ref="addForm" label-width="120px" :model="form" :rules="rules">
        <el-form-item label="部门名称" prop="name">
          <el-input
            v-model="form.name"
            style="width: 80%"
            placeholder="1-50个字符"
          />
        </el-form-item>
        <el-form-item label="部门编码" prop="code">
          <el-input
            v-model="form.code"
            style="width: 80%"
            placeholder="1-50个字符"
          />
        </el-form-item>
        <el-form-item label="部门负责人" prop="manager">
          <!-- label就是中文文案 value就是选中的值 将来会自动放到form.manafer上 -->
          <el-select
            style="width: 80%"
            placeholder="请选择"
            v-model="form.manager"
          >
            <el-option
              v-for="item in employeeList"
              :key="item.id"
              :label="item.username"
              :value="item.username"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="部门介绍" prop="introduce">
          <el-input
            style="width: 80%"
            placeholder="1-300个字符"
            type="textarea"
            v-model="form.introduce"
          />
        </el-form-item>
      </el-form>
      <!-- 具名插槽 -->
      <template #footer>
        <span slot="footer" class="dialog-footer">
          <el-button @click="showDialog = false">取 消</el-button>
          <el-button type="primary" @click="confirm">确 定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import { getEmployeeSimple } from "@/api/employees";
import {
  addDepartments,
  getDepartDetail,
  updateDepartments,
} from "@/api/departments";
export default {
  props: {
    showDialog: {
      type: Boolean,
    },
    curId: {
      type: String,
      default: "",
    },
    codeList: {
      type: Array,
      default: () => {
        return [];
      },
    },
  },
  data() {
    // 定义一个针对于code不能重复的校验函数
    const validateCode = (rule, value, callback) => {
      // 添加code非重逻辑
      // 思路: 使用value去已经存在的列表中去找 如果找到就重复了 校验不过 如果找不到 不重复 校验通过
      // 1. 通过父传子把数据传过来
      // 2. 去数组中找 includes
      // 3. 在拿到原数组之后有一步树形结构处理的, 不方便做数组查找 传下来的应该是一个未经过处理的原数组

      // 产生问题的原因: 当前输入code回填的数据 能在codeList中找到
      // 解决问题的思路: 在编辑的情况下 用作判断的codeList中应该先过滤掉当前回显时的数据code
      // 具体的核心点:
      // 1. 数组过滤 NodeFilter
      // 2. 拿到当前输入框中code 现在的数据(由于form中的code和表单由双向绑定的关系 只有有输入修改就会被同步改掉 本来用作判断条件的初始code丢失)
      // 另外一个单独的专门用来存放初始code的属性
      let _codeList = []; // 作为判断条件的codeList
      if (this.form.id) {
        // 编辑
        _codeList = this.codeList.filter((item) => item !== this.cacheCode);
      } else {
        _codeList = this.codeList;
      }
      if (_codeList.includes(value)) {
        // 找到了
        callback(new Error("code不能出现重复"));
      } else {
        callback();
      }
    };
    return {
      form: {
        name: "", // 部门名称
        code: "", // 部门编码
        manager: "", // 部门管理者
        introduce: "", // 部门介绍
      },
      cacheCode: "", // 存放初始code
      rules: {
        name: [
          {
            required: true,
            message: "部门名称不能为空",
            trigger: ["blur", "change"],
          },
          {
            min: 1,
            max: 50,
            message: "部门名称要求1-50个字符",
            trigger: ["blur", "change"],
          },
        ],
        code: [
          {
            required: true,
            message: "部门编码不能为空",
            trigger: ["blur", "change"],
          },
          {
            min: 1,
            max: 50,
            message: "部门编码要求1-50个字符",
            trigger: ["blur", "change"],
          },
          {
            validator: validateCode,
            message: "部门编码不能出现重复",
            trigger: "blur",
          },
        ],
        manager: [
          {
            required: true,
            message: "部门负责人不能为空",
            trigger: ["blur", "change"],
          },
        ],
        introduce: [
          {
            required: true,
            message: "部门介绍不能为空",
            trigger: ["blur", "change"],
          },
          {
            min: 1,
            max: 300,
            message: "部门介绍要求1-300个字符",
            trigger: ["blur", "change"],
          },
        ],
      },

      employeeList: [], // 下拉员工列表
    };
  },
  methods: {
    closeDialog() {
      this.$emit("close-dialog");
      //   初始化数据 清理校验结果
      this.form = {
        name: "", // 部门名称
        code: "", // 部门编码
        manager: "", // 部门管理者
        introduce: "", // 部门介绍
      };
      // bug: resetFields方法只能初始化 默认绑定的字段 新增的字段无法处理
      this.$refs.addForm.resetFields();
    },
    // 获取员工列表
    async hGetEmployeeList() {
      const res = await getEmployeeSimple();
      this.employeeList = res.data;
    },
    openDialog() {
      this.hGetEmployeeList();
      // 获取详情的接口发起
      // 新增业务同样可以调起来这个方法 但是新增是不需要回显的
      // this.getDetail();
    },
    // 提交表单接口调用
    confirm() {
      // 新增和编辑都是通过确定按钮 走confirm方法
      // 所以我们需要做当前是新增还是编辑逻辑判断 如果是新增就调用新增接口 如果是编辑就走更新接口

      // 1. 兜底校验
      this.$refs.addForm.validate(async (valid) => {
        if (valid) {
          // 做新增还是编辑的判断 -> form中是否有id 如果有就是编辑 没有就是新增
          if (this.form.id) {
            // todo edit
            await updateDepartments(this.form);
          } else {
            // 2. 调用新增借口
            await addDepartments({ ...this.form, pid: this.curId });
          }
          // 3. 通知父组件更新列表
          this.$emit("update-list");
          // 4. 关闭弹框
          this.closeDialog();
        }
      });
    },
    // 详情数据拉取 搞定id 方法调用(点击编辑按钮之后 id传过去之后)
    async getDetail(id) {
      // 调用接口 回填数据
      const res = await getDepartDetail(id);
      this.form = res.data;
      // 把一开始的code 交给cacheCode
      this.cacheCode = res.data.code;
    },
  },
};
</script>

<style>
</style>